package com.metaverse.backend.web;

import com.metaverse.backend.utils.ObjUtils;
import org.reflections.Reflections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.persistence.Entity;
import java.util.*;

@RestController
@RequestMapping("/dev")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public class DevelopController {
    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    @GetMapping("/entities")
    public List entities() {
        List<Map<String, String>> entities = new ArrayList<>();
        Reflections reflections = new Reflections(this.getClass().getPackage().getName().replace(".web", ".domain"));
        Set<Class<?>> entitySet = reflections.getTypesAnnotatedWith(Entity.class);
        for (Class<?> entity : entitySet) {
            Map<String, String> map = new HashMap<>();
            map.put("name", entity.getSimpleName());
            map.put("package", entity.getName());
            entities.add(map);
        }
        return entities;
    }

    @GetMapping("/getFields")
    public String[] getFields(@RequestParam String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        return ObjUtils.getFields(Class.forName(className).newInstance().getClass());
    }


    @GetMapping("/mappings")
    @ResponseBody
    public List list() {
        List<HashMap<String, String>> urlList = new ArrayList<>();

        Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> m : map.entrySet()) {
            HashMap<String, String> hashMap = new HashMap<>();
            RequestMappingInfo info = m.getKey();
            HandlerMethod method = m.getValue();
            PatternsRequestCondition p = info.getPatternsCondition();
            for (String url : p.getPatterns()) {
                hashMap.put("url", url);
            }
            hashMap.put("className", method.getMethod().getDeclaringClass().getName()); // 类名
            hashMap.put("method", method.getMethod().getName()); // 方法名
            RequestMethodsRequestCondition methodsCondition = info.getMethodsCondition();
            String type = methodsCondition.toString();
            if (type != null && type.startsWith("[") && type.endsWith("]")) {
                type = type.substring(1, type.length() - 1);
                hashMap.put("type", type); // 方法名
            }
            urlList.add(hashMap);
        }
        return urlList;
    }

    @GetMapping("/selectMappings")
    @ResponseBody
    public List selectMappings() {

        List<HashMap<String, String>> urlList = new ArrayList<>();

        Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> m : map.entrySet()) {
            HashMap<String, String> hashMap = new HashMap<>();
            RequestMappingInfo info = m.getKey();
            HandlerMethod method = m.getValue();
            PatternsRequestCondition p = info.getPatternsCondition();
            for (String url : p.getPatterns()) {
                hashMap.put("url", url);
            }
            urlList.add(hashMap);
        }
        return urlList;
    }
}
